package JavaDesignModel;
// 实验六  装饰模式

// 饮料抽象类（抽象组件）
// 定义奶茶的基本操作
abstract class Beverage {
    protected String description = "未知饮料";

    // 获取饮料描述
    // @return 饮料描述
    public String getDescription() {
        return description;
    }

    // 计算饮料价格
    // @return 价格
    public abstract double cost();

    // 获取配料信息
    // @return 配料信息
    public String getCondiments() {
        return "";
    }

    // 显示订单信息
    public void display() {
        System.out.println("=== 奶茶订单信息 ===");
        System.out.println("饮料描述: " + getDescription());
        System.out.println("总价格: " + cost() + "元");
        System.out.println("使用小料: " + getCondiments());
    }
}

// 绿茶茶底（具体组件）
class GreenTea extends Beverage {
    public GreenTea() {
        description = "绿茶茶底";
    }

    @Override
    public double cost() {
        return 5.0; // 绿茶茶底5元
    }
}

// 乌龙茶茶底（具体组件）
class OolongTea extends Beverage {
    public OolongTea() {
        description = "乌龙茶茶底";
    }

    @Override
    public double cost() {
        return 5.0; // 乌龙茶茶底5元
    }
}

// 配料装饰者抽象类（抽象装饰者）
abstract class CondimentDecorator extends Beverage {
    protected Beverage beverage; // 被装饰的饮料

    public CondimentDecorator(Beverage beverage) {
        this.beverage = beverage;
    }

    //在每个具体装饰类中的Beverage beverage变量都充当了尾指针，指向了上一级被装饰的类
    //而在每个具体装饰类中，重写的getDescription()和cost()方法中，都调用了beverage.getDescription()和beverage.cost()
    //这就实现了递归调用，最终到达了被装饰的组件类（如绿茶茶底或乌龙茶茶底）。
}

// 芋泥配料（具体装饰者）
class Taro extends CondimentDecorator {
    public Taro(Beverage beverage) {
        super(beverage);
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + " + 芋泥";
    }

    @Override
    public String getCondiments() {
        String baseCondiments = beverage.getCondiments();
        return baseCondiments.isEmpty() ? "芋泥" : baseCondiments + ", 芋泥";
    }

    @Override
    public double cost() {
        return beverage.cost() + 1.0; // 芋泥加1元
    }
}

// 糖配料（具体装饰者）
class Sugar extends CondimentDecorator {
    public Sugar(Beverage beverage) {
        super(beverage);
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + " + 糖";
    }

    @Override
    public String getCondiments() {
        String baseCondiments = beverage.getCondiments();
        return baseCondiments.isEmpty() ? "糖" : baseCondiments + ", 糖";
    }

    @Override
    public double cost() {
        return beverage.cost() + 0.2; // 糖加0.2元
    }
}

// 奶盖配料（具体装饰者）
class CheeseFoam extends CondimentDecorator {
    public CheeseFoam(Beverage beverage) {
        super(beverage);
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + " + 奶盖";
    }

    @Override
    public String getCondiments() {
        String baseCondiments = beverage.getCondiments();
        return baseCondiments.isEmpty() ? "奶盖" : baseCondiments + ", 奶盖";
    }

    @Override
    public double cost() {
        return beverage.cost() + 2.0; // 奶盖加2元
    }
}

// 奶茶店测试类
public class MilkTeaShop {
    public static void main(String[] args) {
        // 构造一个添加了两份芋泥一份奶盖的使用绿茶茶底的奶茶
        Beverage myMilkTea = new GreenTea(); // 绿茶茶底
        myMilkTea = new Taro(myMilkTea);     // 第一份芋泥
        myMilkTea = new Taro(myMilkTea);     // 第二份芋泥
        myMilkTea = new CheeseFoam(myMilkTea); // 奶盖

        // 显示订单信息
        myMilkTea.display();
    }
}